package ms.unicorn.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ms.unicorn.NotificationService;

public class NotificationServiceImpl implements NotificationService {

	private Map<Integer, List<Subscriber<?,?>>> subscribers;
	
	static class SubscriptionImpl<DataType, ResultType> implements Subscription<DataType, ResultType> {

		private int event;
		private DataType data;
		private ResultType result;
		
		public SubscriptionImpl(int event, DataType data) {
			this.event = event;
			this.data = data;
			this.result = null;
		}

		@Override
		public int getEvent() {
			return this.event;
		}

		@Override
		public DataType getData() {
			return this.data;
		}

		@Override
		public ResultType getResult() {
			return this.result;
		}

		@Override
		public void setResult(ResultType result) {
			this.result = result;
		}
		
	}
	
	public NotificationServiceImpl() {
		subscribers = new HashMap<Integer, List<Subscriber<?,?>>>();
	}
	
	@Override
	public Subscriber<?,?> registerSubscriber(Subscriber<?,?> subscriber) {
		for (int channel: subscriber.getPreferChannels()) {
			List<Subscriber<?,?>> list = subscribers.get(channel);
			if (list == null)
				subscribers.put(channel, list = new ArrayList<Subscriber<?,?>>());
			if (list.indexOf(subscriber) < 0)
				list.add(subscriber);
		}
		return subscriber;
	}

	@Override
	public void unregisterSubscriber(Subscriber<?,?> subscriber) {
		
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Object dispatch(Object sender, int channel, Subscription<?,?> subscription) {
		List<Subscriber<?,?>> list = subscribers.get(channel);
		if (list != null)
			for (Subscriber subscriber: list) {
				int result = subscriber.hanldeSubscription(sender, channel,subscription);
				switch (result) {
				case SUBSCRIPTION_EXPIRED:
					return subscription.getResult();
				}
			}
		return subscription.getResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public <DataType, ResultType> ResultType dispatch(Object sender, int channel, int event, DataType data) {
		return (ResultType) dispatch(sender, channel, new SubscriptionImpl<DataType, ResultType>(event, data));
	}

}
